package staff.io;

import static staff.util.XmlUtils.XML_EMPLOYE_TAG;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import staff.logic.Employee;

/** Class for loading employes from XML. Using DOM. */
public class DOMEmployeLoader implements EmployeLoader {
    private NodeList employesNodeList;
    private int currentEmployeNo = 0;

    /** Constructor */
    public DOMEmployeLoader(String fileName)
            throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        Document document = documentBuilder.parse(new File(fileName));
        Element root = document.getDocumentElement();
        employesNodeList = root.getElementsByTagName(XML_EMPLOYE_TAG);
    }

    /** Has next employe to load */
    public boolean hasNext() {
        return (currentEmployeNo < employesNodeList.getLength());
    }

    /** Load next employe */
    public Employee loadNext() {
        if (hasNext()) {
            Node employeNode = employesNodeList.item(currentEmployeNo++);
            Employee result = getEmployeFromNode(employeNode);
            return result;
        } else {
            throw new IllegalStateException("There is no more employe to load.");
        }
    }

    public void close() {
        // it seems like nothing need to close here
    }

    /** Get employe from XML node */
    private Employee getEmployeFromNode(Node employeNode) {
        Employee result = new Employee();
        // bypass all child nodes to take parameters
        for (Node child = employeNode.getFirstChild(); child != null; child = child
                .getNextSibling()) {
            // check that node is parameter
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                getParamFromNode(result, child);
            }
        }
        return result;
    }

    /** Get employe param from XML node */
    private void getParamFromNode(Employee employe, Node node) {
        String paramName = node.getNodeName();
        String paramValue = null;
        if (node.hasChildNodes()) {
            Node child = node.getFirstChild();
            paramValue = child.getNodeValue();
        }
        if (paramValue != null) {
            employe.setParamByName(paramName, paramValue);
        }
    }

}
